﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tracy.Messages;
using Tracy.DataModel;
using Tracy.Properties;
using System.IO;
using Tracy.BasicServices;
using SharedLib.Helpers;
using SharedLib.BasicServices.MessageFramework;

namespace Tracy.Handlers
{
    public class FileMonitorHandler : TaskMessageHandler
    {
        protected override void ProcessMessage(TaskMessage msg)
        {
            if (msg != null)
            {
                List<MediaFile> updatedFiles = new List<MediaFile>();
                if (msg.Data == null)
                {
                    CheckIncompleteFiles(updatedFiles);
                }
                else if (msg.Data is MediaFile)
                {
                    MediaFile file = msg.Data as MediaFile;
                    if (CheckSingleFile(file))
                    {
                        updatedFiles.Add(file);
                    }
                }

                if (updatedFiles.Count > 0)
                {
                    TracyBus.Instance.MessageDispatcher.NotifyUI(msg, NotifyUIEventArgs.FILE_UPDATED, updatedFiles);
                }
            }
        }




        /// <summary>
        /// Check file status
        /// </summary>
        /// <param name="mediaFile"></param>
        /// <returns>Is File Status Changed</returns>
        private bool CheckSingleFile(MediaFile file)
        {
            string fullPath = file.GetTempFilePath(Settings.Default.DefaultDownloadFolder);
            string tempFullPath = file.GetDownloadingFilePath(Settings.Default.DefaultDownloadFolder);
            string newFullPath = file.GetSavedFilePath();
            
            switch (file.Status)
            {
                case "Missing":
                case "New":
                    if(File.Exists(newFullPath))
                    {
                        MarkAsReady(file);
                        return true;
                    }
                    else if (File.Exists(fullPath))
                    {
                        file.Status = "Copying";
                        BeginCopyFile(file, fullPath, newFullPath);
                        //TracyBus.Instance.MessageDispatcher.EnqueueMessage(new TaskMessage(this, typeof(FileMonitorHandler), file, null));
                        return true;
                    }
                    else if (File.Exists(tempFullPath))
                    {
                        file.Status = "In Progress";
                        return true;
                    }
                    break;

                case "In Progress":
                    if (File.Exists(newFullPath))
                    {
                        file.Status = "Ready";
                        return true;
                    }
                    else if (File.Exists(fullPath))
                    {
                        file.Status = "Copying";
                        BeginCopyFile(file, fullPath, newFullPath);
                        //TracyBus.Instance.MessageDispatcher.EnqueueMessage(new TaskMessage(this, typeof(FileMonitorHandler), file, null));
                        return true;
                    }
                    else if (!File.Exists(tempFullPath))
                    {
                        file.Status = "Missing";
                        return true;
                    }
                    break;
                case "Copying":
                case "Moving":
                    if (File.Exists(newFullPath))
                    {
                        MarkAsReady(file);
                        return true;
                    }
                    else if (File.Exists(fullPath))
                    {
                        BeginCopyFile(file, fullPath, newFullPath, file.Status == "Copying");
                        return false;
                    }
                    else
                    {
                        file.Status = "Missing";
                        return true;
                    }
                case "Ready":
                case "Watched":
                    if (!File.Exists(newFullPath))
                    {
                        file.Properties[MediaFile.KEY_PREVIOUS_STATUS] = file.Status;
                        file.Status = "Missing";//TODO: Support removable device
                        return true;
                    }
                    break;
            }
            return false;
        }


        private void MarkAsReady(MediaFile file)
        {
            if (file.Properties.ContainsKey(MediaFile.KEY_PREVIOUS_STATUS))
            {
                file.Status = file.Properties[MediaFile.KEY_PREVIOUS_STATUS];
                file.Properties.Remove(MediaFile.KEY_PREVIOUS_STATUS);
            }
            else
            {
                file.Status = "Ready";
            }
        }

        private void CheckIncompleteFiles(List<MediaFile> updatedFiles)
        {
            foreach (MediaFile file in TracyBus.Instance.MediaFileProvider.GetIncompleteFiles())
            {
                if (CheckSingleFile(file)) updatedFiles.Add(file);
            }
        }

        private void BeginCopyFile(MediaFile file, string sourceFile, string destinationFile, bool copyFile = true)
        {
            CopyFileMessage msg = new CopyFileMessage(this, sourceFile, destinationFile, file, EndCopyFile);
            if (!copyFile) msg.Mode = CopyFileMessage.CopyFileMode.Move;
            TracyBus.Instance.MessageDispatcher.EnqueueMessage(msg);
            //IOHelper.CopyFile(sourceFile, destinationFile);
            //file.Status = "Ready";
        }

        private void EndCopyFile(IAppMessage msg)
        {
            if (msg != null && msg.Data != null && msg.Data is MediaFile)
            {
                List<MediaFile> updatedFiles = new List<MediaFile>();
                MediaFile copiedFile = msg.Data as MediaFile;
                MarkAsReady(copiedFile);
                //if (copiedFile.Properties.ContainsKey(MediaFile.KEY_PREVIOUS_PATH)) copiedFile.Properties.Remove(MediaFile.KEY_PREVIOUS_PATH);
                updatedFiles.Add(copiedFile);
                TracyBus.Instance.MessageDispatcher.NotifyUI(msg, NotifyUIEventArgs.FILE_UPDATED, updatedFiles);
            }
        }
    }
}
